package com.woniuxy.java106crm.config;

import com.woniuxy.java106crm.filter.AuthFilter;
import com.woniuxy.java106crm.handler.CustomAccessDeniedHandler;
import com.woniuxy.java106crm.service.CustomUserDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/**
 * 配置认证信息
 * 用户账号、密码、角色、权限等信息
 */
@Slf4j
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启security的注解控制权限功能，默认是未开启
public class AuthConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private CustomUserDetailService customUserDetailService;

    @Resource
    private AuthFilter authFilter;
    /**
     * 指定用户信息的方法
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //设置用户信息的service 指定用户信息从何而来
        //NoOpPasswordEncoder不对密码做任何加密处理
        //BCryptPasswordEncoder采用MD5算法对用户登录提交的密码进行加密处理
        auth.userDetailsService(customUserDetailService).passwordEncoder(new BCryptPasswordEncoder());
    }
    /**
     * 大范围的访问控制
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //antMatchers指定匹配的路径
        //permitAll不需要认证即可访问
        //formLogin 一旦配置了哪些能够直接访问，哪些是需要认证之后才能访问，security默认关闭了表单的登录和登出
        //anyRequest 剩下其他所有的请求
        //authenticated 必须要认证之后才能访问
        //exceptionHandling 开启异常处理功能
        //accessDeniedHandler 指定无权限的异常处理器
        http.authorizeHttpRequests()
                .antMatchers("/user/login","/images/**","/loginInfo/**",
                        "/WebSocketHandler/**","/swagger-ui.html","/webjars/**","/v2/**","/swagger-resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new CustomAccessDeniedHandler())
                .and()
                .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
                .formLogin()
                .and()
                .csrf().disable();//关闭csrf防御
    }

    //配置认证管理器，默认没有创建，如果需要则创建，添加ioc容器中
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
